package progetto.gruppo0506;

import java.util.GregorianCalendar;
import java.util.LinkedList;
import java.util.Random;

import android.util.Log;

public class Percorso {
	private final static String AUTOMOBILE = "driving";

	private GooglePlaces google;

	private CostoPOItoPOI[][] matriceCosti;
	private LinkedList<POIItinerario> inItinerario;
	private int numPOI;

	public Percorso(LinkedList<POIItinerario> inItinerario, Localizzazione loc,
			GooglePlaces google, PreferenzeUtente p) {
		this.google = google;

		this.inItinerario = inItinerario;
		POIItinerario corrente = new POIItinerario("PosizioneCorrente",
				loc.getLongitudine(), loc.getLatitudine());
		corrente.setInizioVisita(new GregorianCalendar());
		corrente.setFineVisita(new GregorianCalendar());
		this.inItinerario.addFirst(corrente);
		numPOI = this.inItinerario.size();

		elaboraCosti();
		elaboraPercorso(p);
	}

	private void elaboraCosti() {
		POIItinerario partenza;
		POIItinerario destinazione;

		matriceCosti = new CostoPOItoPOI[numPOI][numPOI];

		for (int i = 0; i < numPOI; i++) {
			partenza = inItinerario.get(i);

			for (int j = 0; j < numPOI; j++) {
				destinazione = inItinerario.get(j);

				if (i == j) {
					matriceCosti[i][j] = new CostoPOItoPOI();
					matriceCosti[i][j].setDistanza(Integer.MAX_VALUE);
					matriceCosti[i][j].setTempo(0);

				} else {
					matriceCosti[i][j] = google.richiestaCostiPOItoPOI(
							partenza.getLatitudine(),
							destinazione.getLatitudine(),
							partenza.getLongitudine(),
							destinazione.getLongitudine(), AUTOMOBILE);
					matriceCosti[i][j].setDistanza(50 * (i + 1));
					matriceCosti[i][j].setTempo(3600);
				}
				Log.i("i->" + i + "---j->" + j,
						"|" + matriceCosti[i][j].getDistanza() + "|");
			}

		}

	}

	private void elaboraPercorso(PreferenzeUtente preferenze) {
		int indexmin;

		int riga = 0;
		int colonna = 0;

		
		resetColonnaMatrice(0);
		LinkedList<POIItinerario> elencoOrdinato = new LinkedList<POIItinerario>();

		GregorianCalendar fine = new GregorianCalendar();
		Log.i("Inizio", "" + String.valueOf(fine.get(GregorianCalendar.YEAR)) + " " +
				String.valueOf(fine.get(GregorianCalendar.MONTH)) + " " +
				String.valueOf(fine.get(GregorianCalendar.DAY_OF_MONTH)) + " " +
				String.valueOf(fine.get(GregorianCalendar.HOUR_OF_DAY)) + " " +
				String.valueOf(fine.get(GregorianCalendar.MINUTE)) +" " +
				String.valueOf(fine.get(GregorianCalendar.SECOND)));
				
		while (colonna < numPOI - 1) {
			Log.i("Riga: ", String.valueOf(riga));
			indexmin = searchMinRiga(riga);

			POIItinerario corrente = inItinerario.get(indexmin);

			Log.i("Ciao Gino", String.valueOf(indexmin));

			GregorianCalendar inizio = new GregorianCalendar();
			inizio.set(fine.get(GregorianCalendar.YEAR),
					fine.get(GregorianCalendar.MONTH),
					fine.get(GregorianCalendar.DAY_OF_MONTH),
					fine.get(GregorianCalendar.HOUR_OF_DAY),
					fine.get(GregorianCalendar.MINUTE),
					fine.get(GregorianCalendar.SECOND)
							+ matriceCosti[riga][indexmin].getTempo());
			

			corrente.setInizioVisita(inizio);

			fine = new GregorianCalendar();
			fine.set(
					inizio.get(GregorianCalendar.YEAR),
					inizio.get(GregorianCalendar.MONTH),
					inizio.get(GregorianCalendar.DAY_OF_MONTH),
					inizio.get(GregorianCalendar.HOUR_OF_DAY),
					inizio.get(GregorianCalendar.MINUTE)
							+ corrente.getMinutiPermanenza(),
					inizio.get(GregorianCalendar.SECOND));

			corrente.setFineVisita(fine);

			elencoOrdinato.add(corrente);

			resetColonnaMatrice(indexmin);

			riga = indexmin;
			colonna++;
		}

		inItinerario = elencoOrdinato;
	}

	public LinkedList<POIItinerario> getElenco() {
		return inItinerario;
	}

	private int searchMinRiga(int riga) {
		int index = 0;

		for (int i = 0; i < numPOI; i++) {
			Log.i("i->", "" + i);
			if (matriceCosti[riga][i].getDistanza() < matriceCosti[riga][index]
					.getDistanza()) {
				index = i;
			}

		}
		return index;
	}

	private void resetColonnaMatrice(int colonna) {
		for (int i = 0; i < numPOI; i++) {
			matriceCosti[i][colonna].setDistanza(Integer.MAX_VALUE);
		}
	}
}